package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.aiassistant.domain.entity.AiCustomerEntity;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.elasticsearch.constant.EsNormalConstant;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.EnableApiCallBack;
import com.xbongbong.paas.util.DataUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.SpecialUpdateCustomerDataEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.ApiCallBackEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.CustomerDao;
import com.xbongbong.saas.domain.entity.CustomerSubDataEntity;
import com.xbongbong.saas.domain.entity.FineClueScriptEntity;
import com.xbongbong.saas.domain.entity.RuleCustomerEntity;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.DistributorEnum;
import com.xbongbong.saas.enums.subform.CustomerTeamEnum;
import com.xbongbong.saas.help.ShowFormatHelp;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerSubDataModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.saas.util.StandardizeDataUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.join.query.HasChildQueryBuilder;
import org.elasticsearch.join.query.JoinQueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.ScriptSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author feng.zheng
 * @version v1.0
 * @date 2019/1/22 16:44
 * @since v1.0
 */
@Service("customerModel")
public class CustomerModelImpl  implements CustomerModel {

    private static final Logger LOG = LoggerFactory.getLogger(CustomerModelImpl.class);
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private CustomerDao customerDao;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private CustomerSubDataModel customerSubDataModel;
    @Resource
    private ShowFormatHelp showFormatHelp;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private IndexTypeModel indexTypeModel;

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.CUSTOMER, operateTypeEnum = OperateTypeEnum.NEW)
    public Integer insert(CustomerEntityExt entity) throws XbbException {
        if (Objects.isNull(entity.getSerialNo())) {
            entity.setSerialNo("");
        }
        long now = DateUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);

        paasFormSubDataModel.transferSubForm(entity, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        StandardizeDataUtil.standardizeNotString(entity);
        Integer success = customerDao.insert(entity);
        PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
        BeanUtil.copyProperties(entity, paasFormDataEntity);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(entity.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        InsertDTO insertDTO = paasEsModel.getSaveDTO(paasFormDataEntity, indexTypeEnum);
        paasEsModel.insert(insertDTO);

        paasFormSubDataModel.insertSubFormData(entity, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);

        return success;
    }


    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.CUSTOMER, operateTypeEnum = OperateTypeEnum.EDIT)
    public Integer update(CustomerEntityExt entity) throws XbbException {
        long now = DateUtil.getInt();
        entity.setUpdateTime(now);

        paasFormSubDataModel.transferSubForm(entity, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);

        StandardizeDataUtil.standardizeNotString(entity);
        Integer success = customerDao.update(entity);
        Integer updateSub = paasFormSubDataModel.updateSubFormData(entity, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);

        if (Objects.equals(1, success) || Objects.equals(1, updateSub)) {
            // 更新时间
            success = customerDao.updateTime(now+1, entity.getId(), entity.getCorpid());
            // 更新es
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(entity, paasFormDataEntity, false);
            IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(entity.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
            removeSysDate(paasFormDataEntity);
            InsertDTO insertDTO = paasEsModel.getSaveDTO(paasFormDataEntity, indexTypeEnum);
            insertDTO.getSource().remove("creatorId");
            paasEsModel.update(insertDTO);
        }
        if (Objects.nonNull(entity.getSubFormData()) && !entity.getSubFormData().isEmpty()) {
            entity.getData().putAll(entity.getSubFormData());
        }

        return success;
    }

    private void removeSysDate(PaasFormDataEntity paasFormDataEntity) {
        if (Objects.nonNull(paasFormDataEntity.getData())) {
            JSONObject jsonObject = paasFormDataEntity.getData();
            jsonObject.remove(CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr());
            jsonObject.remove(CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr());
            paasFormDataEntity.setData(jsonObject);
        }
    }


    @Override
    public List<CustomerEntityExt> findEntitys(Map<String, Object> param) {
        List<CustomerEntityExt> entitys = customerDao.findEntitys(param);
        Object corpid = param.get(ParameterConstant.CORPID);
        if (Objects.nonNull(corpid)) {
            paasFormSubDataModel.findSubEntity(corpid.toString(), entitys, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        }
        return entitys;
    }


    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return customerDao.getEntitysCount(param);
    }

    @Override
    public CustomerEntityExt getByKey(Long key, String corpid) {
        CustomerEntityExt customerEntityExt = customerDao.getByKey(key, corpid);
        paasFormSubDataModel.findSubEntity(corpid, Collections.singletonList(customerEntityExt), IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        return customerEntityExt;
    }

    @Override
    public List<CustomerEntityExt> getByKeys(List<Long> keys, String corpid) {

        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("ids", keys);
        param.put("del", BasicConstant.ZERO);

        return findEntitys(param);
    }

    /**
     * 按手机号查询客户
     *
     * @param corpid 公司ID
     * @param phone  用于判重的手机号
     * @return CustomerEntityExt
     * @author youli.chen
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public CustomerEntityExt getByPhone(String corpid, String phone) throws XbbException{
        if (StringUtil.isEmpty(phone)) {
            return null;
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        // 电话拨打，采用精确查询
        boolQueryBuilder.filter(termQuery("data."+ CustomerManagementEnum.PHONE.getAttr() + "." + StringConstant.PHONE_TEL_ATTR + ".keyword", phone));
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, 1);
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<CustomerEntityExt> customerEntityExtList = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, CustomerEntityExt.class);
        if (customerEntityExtList.getContent().size() == 0) {
            return null;
        } else {
            CustomerEntityExt customerEntityExt = customerEntityExtList.getContent().get(0);
            paasFormSubDataModel.findSubEntity(corpid, Collections.singletonList(customerEntityExt), IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
            return customerEntityExt;
        }
    }
    @Override
    public CustomerEntityExt getByPhoneIncloudRecycled(String corpid, String phone) throws XbbException{
        if (StringUtil.isEmpty(phone)) {
            return null;
        }
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
//        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery("del", Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.DELETE.getDel())));
        // 电话拨打，采用精确查询
        boolQueryBuilder.filter(termQuery("data."+ CustomerManagementEnum.PHONE.getAttr() + "." + StringConstant.PHONE_TEL_ATTR + ".keyword", phone));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
        sourceBuilder.query(boolQueryBuilder);

        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, 1);
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<CustomerEntityExt> customerEntityExtList = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, CustomerEntityExt.class);
        if (customerEntityExtList.getContent().size() == 0) {
            return null;
        } else {
            CustomerEntityExt customerEntityExt = customerEntityExtList.getContent().get(0);
            paasFormSubDataModel.findSubEntity(corpid, Collections.singletonList(customerEntityExt), IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
            return customerEntityExt;
        }
    }

    @Override
    public List<CustomerEntityExt> getCustomerByDateInOneDay(String corpid, String attr, Long formId, Long time) {
        String attrStr = "$." + attr;
        Long startTime = DateTimeUtil.getTodayInt(time);
        Long endTime = startTime + 86400;
        List<CustomerEntityExt> customerByDateInOneDay = customerDao.getCustomerByDateInOneDay(corpid, attrStr, formId, startTime, endTime);
        paasFormSubDataModel.findSubEntity(corpid, customerByDateInOneDay, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        return customerByDateInOneDay;
    }



    @Override
    public List<RuleCustomerEntity> getMainCustomerList4Rule(String corpid, List<Long> idIn, Long menuId) {
        return customerDao.getMainCustomerList4Rule(corpid, idIn, menuId);
    }

    @Override
    public List<RuleCustomerEntity> getMainCustomerListByUserId(String corpid, String userId, Integer importantDegreeInt, Integer pageNum, Integer pageSize, String orderField, List<Integer> sortList, List<Long> customerIdIn, Long menuId) throws XbbException {
        //当没有客户集合时
        if(customerIdIn != null && customerIdIn.size() == 0){
            return new ArrayList<>();
        }
        return getMainCustomerListByUserIdFromEs(corpid, userId, importantDegreeInt, pageNum, pageSize, orderField, sortList, customerIdIn, menuId);
    }

    private List<RuleCustomerEntity> getMainCustomerListByUserIdFromEs(String corpid, String userId, Integer importantDegreeInt, Integer pageNum, Integer pageSize, String attr, List<Integer> sortList, List<Long> customerIdIn, Long menuId) throws XbbException {
        //为0时，表示没有超过最大客户数据
        if (Objects.equals(pageSize, 0)) {
            return new ArrayList<>();
        }
        IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        IndexTypeEnum customerTeamIndex = indexTypeModel.getCustomerTeamIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Integer importantDegreeMax = null;
        Integer importantDegree = null;
        if(importantDegreeInt != null){
            if(Objects.equals(importantDegreeInt, 1)){
                importantDegreeMax = importantDegreeInt;
            }else{
                importantDegree = importantDegreeInt;
            }
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        if (Objects.nonNull(menuId)) {
            boolQueryBuilder.filter(termQuery("menuId", menuId));
        }
        if (Objects.nonNull(importantDegree)) {
            boolQueryBuilder.filter(termQuery(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.IMPORTANT_DEGREE), importantDegree));
        }
        if (Objects.nonNull(importantDegreeMax)) {
            boolQueryBuilder.filter(rangeQuery(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.IMPORTANT_DEGREE))
                    .lte(importantDegreeMax));
        }
        if (CollectionsUtil.isNotEmpty(customerIdIn)) {
            boolQueryBuilder.filter(termsQuery(StringConstant.DATA_ID, customerIdIn));
        }
        HasChildQueryBuilder hasChildQueryBuilder = esHelper.teamQueryBuilder(customerTeamIndex, corpid, BasicConstant.ONE, Arrays.asList(userId));
        boolQueryBuilder.filter(hasChildQueryBuilder);
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,customerIndex.getType()));
        sourceBuilder.query(boolQueryBuilder);
        List<String> fieldList = Arrays.asList(StringConstant.DATA_ID, "appId", "formId", "menuId", "corpid",
                CustomerManagementEnum.NAME.getAttr(), CustomerManagementEnum.LAST_CONNECT_TIME.getAttr(),
                CustomerManagementEnum.TYPE.getAttr(), CustomerManagementEnum.LABEL.getAttr(),
                CustomerManagementEnum.IMPORTANT_DEGREE.getAttr());
        EsUtil.setFieldList(sourceBuilder, fieldList);
        SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
        if (Objects.isNull(pageNum) || Objects.equals(pageNum, 0)) {
            pageNum = 1;
        }
        if (Objects.isNull(pageSize)) {
            pageSize = EsNormalConstant.FIND_NUM;
        }
        if (StringUtil.isNotEmpty(attr) && CollectionsUtil.isNotEmpty(sortList)) {
            ScriptSortBuilder scriptSortBuilder = new ScriptSortBuilder(getScript(attr, sortList), ScriptSortBuilder.ScriptSortType.NUMBER);
            sourceBuilder.sort(scriptSortBuilder);
        } else {
            sourceBuilder.sort("dataId", SortOrder.ASC);
        }
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, pageNum, pageSize);
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<CustomerEntityExt> customerEntityExtList = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, CustomerEntityExt.class);
        List<CustomerEntityExt> customerEntityExts = customerEntityExtList.getContent();
        return formatRuleCustomer(customerEntityExts);
    }

    /**
     * 获取排序脚本
     * @param attr
     * @param sortList
     * @return
     * @throws XbbException
     */
    private Script getScript(String attr, List<Integer> sortList) throws XbbException {
        if (StringUtil.isEmpty(attr) || CollectionsUtil.isEmpty(sortList)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "排序参数错误！");
        }
        String scriptStr = null;
        if (Objects.equals(attr, CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.TYPE))) {
            scriptStr = getStringScriptStr(attr);
        } else if (Objects.equals(attr, CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.IMPORTANT_DEGREE))) {
            scriptStr = getNumScriptStr(attr);
        }
        return new Script(ScriptType.INLINE, "painless", scriptStr, getParams(sortList));
    }

    private Map<String, Object> getParams(List<Integer> sortList) {
        if (CollectionsUtil.isEmpty(sortList)) {
            return new HashMap<>();
        }
        //预设的排序值数量
        Integer sortNum = 30;
        //存排序字段的值，若排序字段值的数量不到30，则由大数据补齐，9999-(29-index)
        //values[0]:1, values[1]:10, values[2]:3, values[3]:9973, values[4]:9974, ... values[29]:9999
        List<Integer> values = new ArrayList<>();
        //排序权重值
        // 脚本中1被占用从2开始：sortValues[0]:2, sortValues[1]:3, sortValues[2]:4, ... sortValues[29]:31
        List<Integer> sortValues = new ArrayList<>();

        for(int i = 0; i < sortNum; i++){
            //先由需要排序字段的值填充
            if (i < sortList.size()) {
                values.add(sortList.get(i));
            } else {
                values.add( 9999-(29-i) );
            }
            sortValues.add( i + 2 );
        }
        Map<String, Object> params = new HashMap<>();
        params.put("values", values);
        params.put("sortValues", sortValues);
        return params;
    }

    /**
     * if(doc['data.text_4.raw'].size()==0){return 1;}
     * else if(Long.parseLong(doc['data.text_4.raw'].value)==params['values'][0]){return params['sortValues'][0];}
     * else if(Long.parseLong(doc['data.text_4.raw'].value)==params['values'][1]){return params['sortValues'][1];}
     * else if(Long.parseLong(doc['data.text_4.raw'].value)==params['values'][2]){return params['sortValues'][2];}
     * .
     * .
     * .
     * else if(Long.parseLong(doc['data.text_4.raw'].value)==params['values'][29]){return params['sortValues'][29];}
     * return Long.parseLong(doc['data.text_4.raw'].value)
     * @param attr
     * @return
     */
    private String getStringScriptStr(String attr) {
        StringBuffer sb = new StringBuffer();
        //空值处理，key不存在或为空字符串
        //if(doc['
        sb.append("if(doc['");
        //if(doc['data.text_4
        sb.append(attr);
        //if(doc['data.text_4.raw'].size()==0){return 1;}
        sb.append(".raw'].size()==0){return 1;}");
        for (Integer i = 0; i < 30; i++) {
            sb.append("else if(Long.parseLong(doc['");
            sb.append(attr);
            sb.append(".raw'].value)==params['values'][");
            sb.append(i);
            sb.append("]){return params['sortValues'][");
            sb.append(i);
            sb.append("];}");
        }
        sb.append("return Long.parseLong(doc['");
        sb.append(attr);
        sb.append(".raw'].value)");
        return sb.toString();
    }

    /**
     * if(doc['data.num_1'].size()==0){return 1;}
     * else if(doc['data.num_1'].value==params['values'][0]){return params['sortValues'][0];}
     * else if(doc['data.num_1'].value==params['values'][1]){return params['sortValues'][1];}
     * else if(doc['data.num_1'].value==params['values'][2]){return params['sortValues'][2];}
     * .
     * .
     * .
     * else if(doc['data.num_1'].value==params['values'][29]){return params['sortValues'][29];}
     * return doc['data.num_1'].value
     * @param attr
     * @return
     */
    private String getNumScriptStr(String attr) {
        StringBuffer sb = new StringBuffer();

        //空值处理，key不存在或为空字符串
        //if(doc['
        sb.append("if(doc['");
        //if(doc['data.num_1
        sb.append(attr);
        //if(doc['data.num_1'].size()==0){return 1;}
        sb.append("'].size()==0){return 1;}");

        for (Integer i = 0; i < 30; i++) {
            sb.append("else if(doc['");
            sb.append(attr);
            sb.append("'].value==params['values'][");
            sb.append(i);
            sb.append("]){return params['sortValues'][");
            sb.append(i);
            sb.append("];}");
        }
        sb.append("return doc['");
        sb.append(attr);
        sb.append("'].value");
        return sb.toString();
    }

    private List<RuleCustomerEntity> formatRuleCustomer(List<CustomerEntityExt> customerEntityExts) {
        List<RuleCustomerEntity> ruleCustomers = new ArrayList<>();
        for (CustomerEntityExt customerEntity : customerEntityExts) {
            RuleCustomerEntity ruleCustomerEntity = new RuleCustomerEntity();
            ruleCustomerEntity.setId(customerEntity.getDataId());
            ruleCustomerEntity.setAppId(customerEntity.getAppId());
            ruleCustomerEntity.setFormId(customerEntity.getFormId());
            ruleCustomerEntity.setMenuId(customerEntity.getMenuId());
            ruleCustomerEntity.setCorpid(customerEntity.getCorpid());

            JSONObject data = customerEntity.getData();
            String name = data.getString(CustomerManagementEnum.NAME.getAttr());
            Integer type = data.getInteger(CustomerManagementEnum.TYPE.getAttr());
            String labels = data.getString(CustomerManagementEnum.LABEL.getAttr());
            Integer importantDegree = data.getInteger(CustomerManagementEnum.IMPORTANT_DEGREE.getAttr());
            Long lastConnectTime = data.getLong(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr());
            ruleCustomerEntity.setName(name);
            ruleCustomerEntity.setType(type);
            ruleCustomerEntity.setLabels(labels);
            ruleCustomerEntity.setImportantDegree(importantDegree);
            ruleCustomerEntity.setLastConnectTime(lastConnectTime);
            ruleCustomers.add(ruleCustomerEntity);
        }
        return ruleCustomers;
    }

    @Override
    public Integer getMainCustomerCountByUserId(String corpid, String userId, Integer importantDegreeInt) throws XbbException {
        Integer importantDegreeMax = null;
        Integer importantDegree = null;
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
        if(importantDegreeInt != null){
            if(Objects.equals(importantDegreeInt, 1)){
                importantDegreeMax = importantDegreeInt;
                boolQueryBuilder.filter(rangeQuery(CustomerManagementEnum.getEsAttr4Keyword(CustomerManagementEnum.IMPORTANT_DEGREE)).lte(importantDegreeMax));
            }else{
                importantDegree = importantDegreeInt;
                boolQueryBuilder.filter(termQuery(CustomerManagementEnum.getEsAttr4Keyword(CustomerManagementEnum.IMPORTANT_DEGREE), importantDegree));
            }
        }
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        BoolQueryBuilder teamQueryBuilder = boolQuery();
        teamQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        teamQueryBuilder.filter(termQuery(CustomerTeamEnum.getEsAttr(CustomerTeamEnum.IS_MAIN), BasicConstant.ONE));
        teamQueryBuilder.filter(termQuery(CustomerTeamEnum.getEsAttr(CustomerTeamEnum.USER_ID), userId));
        teamQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        HasChildQueryBuilder hasChildQueryBuilder = JoinQueryBuilders.hasChildQuery(IndexTypeEnum.IDX_SAAS_CUSTOMER_TEAM.getType(), teamQueryBuilder, ScoreMode.Max);
        boolQueryBuilder.filter(hasChildQueryBuilder);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        searchRequest.source(sourceBuilder);
        CountRequest countRequest = new CountRequest(searchRequest.indices()[0]);
        countRequest.query(searchRequest.source().query());
        Long countLong = xbbElasticsearchRestTemplate.count(countRequest);
        Integer count = countLong.intValue();
        return count;
    }


    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.CUSTOMER, operateTypeEnum = OperateTypeEnum.EDIT, isBatch = true)
    public Integer updateBatch(List<UpdateDataEntity> updateDataList, String corpid) throws XbbException {
       return updateBatch(updateDataList, corpid, WriteRequest.RefreshPolicy.WAIT_UNTIL);
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.CUSTOMER, operateTypeEnum = OperateTypeEnum.EDIT, isBatch = true)
    public Integer updateBatch(List<UpdateDataEntity> updateDataList, String corpid,WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        //1. 先拿到子表单数据
        List<UpdateDataEntity> subList = DataUtil.getUpdateSubDataList(updateDataList);
        // 2. 主表删掉子表单数据
        DataUtil.removeSubDataInData(updateDataList);
        Integer integer = 0;
        if (CollectionsUtil.isNotEmpty(updateDataList)) {
            StandardizeDataUtil.standardizeList(updateDataList);
            integer = customerDao.updateBatch(updateDataList, corpid);
            IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

            paasEsModel.updateBatchMuchField(updateDataList, indexTypeEnum, refreshPolicy);
        }
        if (!subList.isEmpty()) {
            customerSubDataModel.updateBatch(subList, corpid);
        }
        return integer;
    }

    @Override
    public Integer restoreBatch(List<Long> dataIdList, String corpid, Integer del) throws XbbException{
        Integer count = customerDao.restoreBatch(dataIdList, corpid, del);
        updateBatchDel(dataIdList, corpid, del);

        paasFormSubDataModel.restoreBatch(dataIdList, corpid, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        return count;
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.CUSTOMER, operateTypeEnum = OperateTypeEnum.DELETE, isBatch = true)
    public Integer deleteBatch(List<Long> deleteIdIn, String corpid) throws XbbException {
        return deleteBatch(deleteIdIn, corpid, WriteRequest.RefreshPolicy.WAIT_UNTIL);
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.CUSTOMER, operateTypeEnum = OperateTypeEnum.DELETE, isBatch = true)
    public Integer deleteBatch(List<Long> deleteIdIn, String corpid, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        Integer integer = customerDao.deleteBatch(deleteIdIn, corpid);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        paasEsModel.deleteBatch(deleteIdIn, corpid, DelEnum.DELETE.getDel(), indexTypeEnum, refreshPolicy);
        paasFormSubDataModel.deleteBatchByDataId(deleteIdIn, corpid, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB, DelEnum.DELETE_SUBFORM);
        return integer;
    }

    @Override
    public Integer thoroughDeleteBatch(List<Long> dataIdList, String corpid, Integer del) throws XbbException {
        Integer count = customerDao.thoroughDeleteBatch(dataIdList, corpid, del);
        updateBatchDel(dataIdList, corpid, del);

        List<? extends PaasFormSubDataEntity> entities = paasFormSubDataModel.getByDataIdList(dataIdList, DelEnum.DELETE_SUBFORM.getDel(), corpid, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        customerSubDataModel.updateDel((List<CustomerSubDataEntity>)  entities,corpid,  WriteRequest.RefreshPolicy.NONE, DelEnum.getByDel(del));
        return count;
    }

    @Override
    @EnableApiCallBack(callBackBusiness = ApiCallBackEnum.CUSTOMER, operateTypeEnum = OperateTypeEnum.NEW, isBatch = true)
    public void insertBatch(List<PaasFormDataEntity> customerEntityExtList, boolean isImport) throws XbbException {
        if (CollectionUtils.isEmpty(customerEntityExtList)) {
            return;
        }
        for (PaasFormDataEntity paasFormDataEntity : customerEntityExtList) {
            paasFormSubDataModel.transferSubForm(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        }
        StandardizeDataUtil.standardize4EntityList(customerEntityExtList);
        customerDao.insertBatch(customerEntityExtList);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(customerEntityExtList.get(0).getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        //ES数据插入
        List<InsertDTO> insertList = new ArrayList<>();
        for (PaasFormDataEntity item : customerEntityExtList) {
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(item.getCorpid() + "_" + item.getId());
            item.setDataId(item.getId());
            insertDTO.setSource(BeanUtil.convertBean2Map(item));
            insertDTO.setIndexTypeEnum(indexTypeEnum);
            insertList.add(insertDTO);
        }
        if (isImport) {
            paasEsModel.insertBatch(insertList, WriteRequest.RefreshPolicy.NONE);
        } else {
            paasEsModel.insertBatch(insertList);
        }

        paasFormSubDataModel.insertBatchSubFormData(customerEntityExtList, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
    }

    @Override
    public List<AiCustomerEntity> getCustomerList4Ai(String corpid, List<Long> idIn) {
        return customerDao.getCustomerList4Ai(corpid, idIn);
    }

    private void updateBatchDel(List<Long> dataIdList, String corpid, Integer del) throws XbbException{
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("del", del);
        map.put("updateTime",DateTimeUtil.getInt());
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        paasFormDataEsModel.updateBatch(dataIdList, corpid, map, indexTypeEnum);
    }

    @Override
    public List<CustomerEntityExt> findEntitysWithoutSub(Map<String, Object> param) {
        return customerDao.findEntitys(param);
    }

    @Override
    public void formatUpdateExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        Integer isPublic = FastJsonHelper.getIntegerOrDefaultFromFormData(formatExplainDTO.getResult(), CustomerManagementEnum.IS_PUBLIC.getAttr(), 0);
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, CustomerManagementEnum.CUSTOMER_STAGE.getAttr()) && (Objects.isNull(formatExplainDTO.getFromCopy()) || !formatExplainDTO.getFromCopy())) {
                fieldAttrEntity.setEditable(0);
                fieldAttrEntity.setMemo(I18nMessageUtil.getMessage(I18nStringConstant.FILL_IN_FEEDBACK_MEMO));
            }
            if (Objects.equals(isPublic, 1) && (Objects.isNull(formatExplainDTO.getFromCopy()) || !formatExplainDTO.getFromCopy())) {
                // 复制不走这里
                if (Objects.equals(attr, CustomerManagementEnum.OWNER_ID.getAttr())) {
                    DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
                    defaultAttrPoJo.setDefaultType(null);
                    defaultAttrPoJo.setDefaultValue("");
                    fieldAttrEntity.setDefaultAttr(defaultAttrPoJo);
                    fieldAttrEntity.setEditable(0);
                } else if (Objects.equals(attr, CustomerManagementEnum.COUSERID.getAttr())) {
                    fieldAttrEntity.setEditable(0);
                }
            }
        }
    }

    /**
     * 编辑时将获取数据格式化
     *
     * @param saasAnalysisDataDTO saas编辑数据
     * @param result              要返回的jsonobject
     * @throws XbbException 业务异常
     * @author feng.zheng
     * @date 2019/1/22 15:28
     */
    @Override
    public void formatData(SaasAnalysisDataDTO saasAnalysisDataDTO, JSONObject result) throws XbbException {
        PaasFormExplainEntity customerExplain = paasFormExplainModel.getByFormId(saasAnalysisDataDTO.getFormId(), saasAnalysisDataDTO.getCorpid());
        if (Objects.isNull(customerExplain)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(customerExplain.getExplains(), CustomerManagementEnum.BIRTHDAY.getAttr());
        FieldAttrEntity birthdayField = explainMap.getOrDefault(CustomerManagementEnum.BIRTHDAY.getAttr(), new FieldAttrEntity());
        if (Objects.equals(birthdayField.getFieldType(), FieldTypeEnum.BIRTHDAY.getType()) && Objects.equals(birthdayField.getIsOpen(), 1) && Objects.equals(birthdayField.getVisible(), 1)) {
            showFormatHelp.formatBirthday4Show(result, CustomerManagementEnum.BIRTHDAY.getAttr(), CustomerManagementEnum.BIRTHDAY_FLAG.getAttr());
        }
        showFormatHelp.formatLinkBusiness4Show(result, CustomerManagementEnum.PARENT.getAttr(), CustomerManagementEnum.PARENT_HIDE.getAttr(), CustomerManagementEnum.PARENT.getFieldType());
        // 关联销售线索
        showFormatHelp.formatLinkBusiness4Show(result, CustomerManagementEnum.CLUE_ID.getAttr(), CustomerManagementEnum.CLUE_NAME_ID.getAttr(), CustomerManagementEnum.CLUE_ID.getFieldType());
    }

    @Override
    public void formatUpdateExplainForDistributor(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        Integer isPublic = FastJsonHelper.getIntegerOrDefaultFromFormData(formatExplainDTO.getResult(), DistributorEnum.IS_PUBLIC.getAttr(), 0);
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            // if (Objects.equals(attr, CustomerManagementEnum.CUSTOMER_STAGE.getAttr()) && (Objects.isNull(formatExplainDTO.getFromCopy()) || !formatExplainDTO.getFromCopy())) {
            //     fieldAttrEntity.setEditable(0);
            //     fieldAttrEntity.setMemo(I18nMessageUtil.getMessage(I18nStringConstant.FILL_IN_FEEDBACK_MEMO));
            // }
            if (Objects.equals(isPublic, 1) && (Objects.isNull(formatExplainDTO.getFromCopy()) || !formatExplainDTO.getFromCopy())) {
                // 复制不走这里
                if (Objects.equals(attr, DistributorEnum.OWNER_ID.getAttr())) {
                    DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
                    defaultAttrPoJo.setDefaultType(null);
                    defaultAttrPoJo.setDefaultValue("");
                    fieldAttrEntity.setDefaultAttr(defaultAttrPoJo);
                    fieldAttrEntity.setEditable(0);
                } else if (Objects.equals(attr, DistributorEnum.COUSERID.getAttr())) {
                    fieldAttrEntity.setEditable(0);
                }
            }
        }
    }

    @Override
    public List<CustomerEntityExt> listByInPhone(String corpid, List<String> phoneList, Boolean dontQueryDel) throws XbbException {
        if (CollectionsUtil.isEmpty(phoneList)) {
            return new ArrayList<>();
        }
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        Set<String> phoneSet = phoneList.stream().filter(StringUtil::isNotEmpty).collect(Collectors.toSet());
        if (CollectionsUtil.isEmpty(phoneSet)) {
            return new ArrayList<>();
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        if (!dontQueryDel) {
            boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        } else {
            List<Integer> delList = new ArrayList<>(2);
            delList.add(DelEnum.NORMAL.getDel());
            delList.add(DelEnum.DELETE.getDel());
            boolQueryBuilder.filter(QueryBuilders.termsQuery("del", delList));
        }
        // 电话拨打，采用精确查询
        boolQueryBuilder.filter(QueryBuilders.termsQuery("data."+ CustomerManagementEnum.PHONE.getAttr() + "." + StringConstant.PHONE_TEL_ATTR + ".keyword", phoneSet));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, 500);
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<CustomerEntityExt> customerEntityExtList = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, CustomerEntityExt.class);
        List<CustomerEntityExt> content = customerEntityExtList.getContent();
        if (CollectionUtils.isEmpty(content)) {
            return new ArrayList<>();
        }
        paasFormSubDataModel.findSubEntity(corpid, content, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        return content;
    }

    @Override
    public List<FineClueScriptEntity> getListByPids(String corpid, List<String> pids) {
        return customerDao.getCustomerListByFineCluePids(corpid, pids);
    }

    @Override
    public void jsonsetNoSubById(String corpid, Long id, Map<String, Object> map) throws XbbException {
        StandardizeDataUtil.standardizeMap(map);
        Map<String,Object> map2 = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Object> updateDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        JSONObject jsonObject = new JSONObject();
        Long now = DateTimeUtil.getInt();
        for (Map.Entry<String,Object> entry : map.entrySet()){
            String key = entry.getKey();
            map2.put("$."+key,entry.getValue());
            jsonObject.put(key,entry.getValue());
        }
        updateDataMap.put("data", jsonObject);
        customerDao.jsonSetAndUpdateTime(corpid, id, map2, now);
        InsertDTO insertDTO = new InsertDTO();
        updateDataMap.put(FieldTypeEnum.UPDATETIME.getAlias(), now);
        insertDTO.setSource(updateDataMap);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        insertDTO.setIndexTypeEnum(indexTypeEnum);
        insertDTO.setEsId(corpid+"_"+id);
        paasEsModel.update(insertDTO);
    }

    /**
     * 更改团队相关信息，需要去更新主表更新时间
     *
     * @param customerEntityExt
     * @return
     * @throws XbbException
     */
    @Override
    public Integer updateByChangeTeam(CustomerEntityExt customerEntityExt) throws XbbException {
        paasFormSubDataModel.transferSubForm(customerEntityExt, IndexTypeEnum.IDX_SAAS_CUSTOMER_SUB);
        // 更新时间
        Integer success = customerDao.updateTime(DateTimeUtil.getInt(), customerEntityExt.getId(), customerEntityExt.getCorpid());
        // 更新es
        PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
        BeanUtil.copyProperties(customerEntityExt, paasFormDataEntity);
        InsertDTO insertDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_CUSTOMER);
        insertDTO.getSource().remove("creatorId");
        paasEsModel.update(insertDTO);
        return success;
    }

    /**
     * 更新客户表的更新时间，包含数据库和es
     *
     * @param id 用户id
     * @param corpid 公司id
     * @return
     * @throws XbbException
     */
    @Override
    public void updateTime(Long id,String corpid) throws XbbException {
        Long updateTime = DateTimeUtil.getInt();
        customerDao.updateTime(updateTime,id, corpid);
        InsertDTO insertDTO = new InsertDTO();
        insertDTO.setEsId(corpid+"_"+id);
        Map<String, Object> map = new HashMap<>();
        map.put(FieldTypeEnum.UPDATETIME.getAlias(), updateTime);
        insertDTO.setSource(map);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        insertDTO.setIndexTypeEnum(indexTypeEnum);
        paasEsModel.update(insertDTO);
    }

    @Override
    public Integer updateBatch4Script(List<SpecialUpdateCustomerDataEntity> specialUpdateList) throws XbbException {
        //插入数据库实体
        List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //插入ES实体
        List<InsertDTO> insertEsList = new ArrayList<>();
        for (SpecialUpdateCustomerDataEntity specialUpdateCustomerDataEntity : specialUpdateList) {
            JSONObject temp = new JSONObject();
            Map<String, Object> map = new HashMap<>();
            String corpid = specialUpdateCustomerDataEntity.getCorpid();
            Long dataId = specialUpdateCustomerDataEntity.getId();
            Long sysDate1 = specialUpdateCustomerDataEntity.getSysDate1();
            Long sysDate2 = specialUpdateCustomerDataEntity.getSysDate2();
            if (Objects.isNull(sysDate1) && Objects.isNull(sysDate2)) {
                continue;
            }
            if (Objects.nonNull(sysDate1)) {
                temp.put(CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr(),specialUpdateCustomerDataEntity.getSysDate1());
                map.put(CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr(), sysDate1);
            }

            if (Objects.nonNull(sysDate2)) {
                temp.put(CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr(),specialUpdateCustomerDataEntity.getSysDate2());
                map.put(CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr(), sysDate2);
            }
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(dataId, temp, corpid);
            updateDataEntityList.add(updateData);

            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(corpid+"_" + dataId);
            insertDTO.setSource(map);
            insertDTO.setIndexTypeEnum(indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()));
            insertEsList.add(insertDTO);
        }
        Integer integer = 0;
        if (updateDataEntityList.size() > 0) {
            StandardizeDataUtil.standardizeList(updateDataEntityList);
            integer = customerDao.updateBatch4Script(updateDataEntityList);
        }

        if (insertEsList.size() > 0) {
            paasEsModel.updateBatch(insertEsList,WriteRequest.RefreshPolicy.NONE);
        }

        return integer;
    }

    @Override
    public Integer specialUpdate4SysDate(Long id, JSONObject dataJSONObject, String corpid) throws XbbException {
        UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(id, dataJSONObject, corpid);
        Integer integer = customerDao.updateBatch(Collections.singletonList(updateDataEntity),corpid);
        InsertDTO insertDTO = new InsertDTO();
        insertDTO.setEsId(corpid+"_" + id);
        Map<String, Object> map = new HashMap<>();
        Object sysDate1 = dataJSONObject.get(CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr());
        Object sysDate2 = dataJSONObject.get(CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr());
        if (Objects.nonNull(sysDate1)) {
            map.put(CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr(), sysDate1);
        }
        if (Objects.nonNull(sysDate2)) {
            map.put(CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr(), sysDate2);
        }

        insertDTO.setSource(map);
        insertDTO.setIndexTypeEnum(indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()));
        paasEsModel.update(insertDTO);
        return integer;
    }
    @Override
    public Long getMaxId() throws XbbException {
        return customerDao.getMaxId();
    }

    @Override
    public <T> List<T> getCustomerListByLinkIdIn(String corpid, Long formId, BoolQueryBuilder boolQueryBuilder, Class<T> clazz, String orderField, SortOrder sortOrder,  Integer page, Integer pageSize) throws XbbException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
        sourceBuilder.sort(new FieldSortBuilder(orderField).order(sortOrder));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        searchRequest.source(sourceBuilder);
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, page, pageSize);
        XbbAggregatedPage<T> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, clazz);
        return esEntities.getContent();
    }
}
